#include "core/TrashCodeGenerator.h"
#include "utils/RandomGenerator.h"
#include <QFile>
#include <QTextStream>
#include <QRegularExpression>
#include <QStringList>
#include <random>

TrashCodeGenerator::TrashCodeGenerator() {}
TrashCodeGenerator::~TrashCodeGenerator() {}

int TrashCodeGenerator::injectCode(const QStringList &files)
{
    int injectedCount = 0;
    for (const QString &file : files) {
        if (injectIntoFile(file)) {
            injectedCount++;
        }
    }
    return injectedCount;
}

QString TrashCodeGenerator::generateTrashMethod()
{
    RandomGenerator gen;
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> dist(0, 4);
    
    QString methodName = gen.generateIdentifier(10);
    QString returnType;
    QString methodBody;
    
    // 随机选择返回类型和方法体
    switch (dist(rng)) {
        case 0:
            returnType = "void";
            methodBody = generateComplexMethodBody();
            break;
        case 1:
            returnType = "BOOL";
            methodBody = "    NSInteger value = arc4random_uniform(100);\n"
                        "    return value > 50;";
            break;
        case 2:
            returnType = "NSInteger";
            methodBody = "    NSInteger result = 0;\n"
                        "    for (int i = 0; i < 10; i++) {\n"
                        "        result += arc4random_uniform(10);\n"
                        "    }\n"
                        "    return result;";
            break;
        case 3:
            returnType = "NSString *";
            methodBody = "    NSMutableString *str = [NSMutableString string];\n"
                        "    for (int i = 0; i < 5; i++) {\n"
                        "        [str appendFormat:@\"%d\", arc4random_uniform(10)];\n"
                        "    }\n"
                        "    return [str copy];";
            break;
        default:
            returnType = "id";
            methodBody = "    return @{@\"key\": @(arc4random_uniform(100))};";
            break;
    }
    
    // 随机添加参数
    QString parameters = generateRandomParameters();
    
    return QString("- (%1)%2%3 {\n%4\n}\n")
        .arg(returnType)
        .arg(methodName)
        .arg(parameters)
        .arg(methodBody);
}

QString TrashCodeGenerator::generateTrashClass()
{
    RandomGenerator gen;
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> methodCount(2, 5);
    std::uniform_int_distribution<int> propCount(1, 3);
    
    QString className = gen.generateIdentifier(12);
    QString interface = QString("@interface %1 : NSObject\n").arg(className);
    QString implementation = QString("@implementation %1\n").arg(className);
    
    // 添加属性
    int numProps = propCount(rng);
    for (int i = 0; i < numProps; i++) {
        interface += generateTrashProperty();
    }
    
    interface += "@end\n\n";
    
    // 添加方法
    int numMethods = methodCount(rng);
    for (int i = 0; i < numMethods; i++) {
        implementation += "\n" + generateTrashMethod();
    }
    
    implementation += "\n@end\n";
    
    return interface + implementation;
}

QString TrashCodeGenerator::generateTrashProperty()
{
    RandomGenerator gen;
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> typeIdx(0, 5);
    
    QString propName = gen.generateIdentifier(8);
    QString propType;
    QString attributes;
    
    // 随机选择属性类型和特性
    switch (typeIdx(rng)) {
        case 0:
            propType = "NSString *";
            attributes = "nonatomic, copy";
            break;
        case 1:
            propType = "NSNumber *";
            attributes = "nonatomic, strong";
            break;
        case 2:
            propType = "NSArray *";
            attributes = "nonatomic, strong";
            break;
        case 3:
            propType = "NSDictionary *";
            attributes = "nonatomic, strong";
            break;
        case 4:
            propType = "NSInteger";
            attributes = "nonatomic, assign";
            break;
        default:
            propType = "BOOL";
            attributes = "nonatomic, assign";
            break;
    }
    
    return QString("@property (%1) %2%3;\n")
        .arg(attributes)
        .arg(propType)
        .arg(propName);
}

bool TrashCodeGenerator::injectIntoFile(const QString &filePath)
{
    // 读取文件内容
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return false;
    }
    
    QString content = QString::fromUtf8(file.readAll());
    file.close();
    
    // 查找合适的插入位置
    QString injectedCode;
    
    if (filePath.endsWith(".m") || filePath.endsWith(".mm")) {
        // Objective-C文件
        injectedCode = injectIntoObjCFile(content);
    } else if (filePath.endsWith(".swift")) {
        // Swift文件
        injectedCode = injectIntoSwiftFile(content);
    } else if (filePath.endsWith(".java") || filePath.endsWith(".kt")) {
        // Java/Kotlin文件
        injectedCode = injectIntoJavaFile(content);
    } else {
        return false;
    }
    
    // 写回文件
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return false;
    }
    
    QTextStream out(&file);
    out << injectedCode;
    file.close();
    
    return true;
}

QString TrashCodeGenerator::injectIntoObjCFile(const QString &content)
{
    // 在@implementation中插入方法
    QRegularExpression implRegex("@implementation\\s+\\w+");
    QRegularExpressionMatch match = implRegex.match(content);
    
    if (match.hasMatch()) {
        int insertPos = match.capturedEnd();
        QString trash = "\n" + generateTrashMethod();
        return content.left(insertPos) + trash + content.mid(insertPos);
    }
    
    return content;
}

QString TrashCodeGenerator::injectIntoSwiftFile(const QString &content)
{
    // 在class中插入方法
    QRegularExpression classRegex("class\\s+\\w+[^{]*\\{");
    QRegularExpressionMatch match = classRegex.match(content);
    
    if (match.hasMatch()) {
        int insertPos = match.capturedEnd();
        QString trash = "\n" + generateSwiftTrashMethod();
        return content.left(insertPos) + trash + content.mid(insertPos);
    }
    
    return content;
}

QString TrashCodeGenerator::injectIntoJavaFile(const QString &content)
{
    // 在class中插入方法
    QRegularExpression classRegex("class\\s+\\w+[^{]*\\{");
    QRegularExpressionMatch match = classRegex.match(content);
    
    if (match.hasMatch()) {
        int insertPos = match.capturedEnd();
        QString trash = "\n" + generateJavaTrashMethod();
        return content.left(insertPos) + trash + content.mid(insertPos);
    }
    
    return content;
}

QString TrashCodeGenerator::generateComplexMethodBody()
{
    QStringList bodies = {
        "    NSMutableArray *array = [NSMutableArray array];\n"
        "    for (int i = 0; i < 10; i++) {\n"
        "        [array addObject:@(arc4random_uniform(100))];\n"
        "    }\n"
        "    [array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {\n"
        "        return [obj1 compare:obj2];\n"
        "    }];",
        
        "    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n"
        "        NSInteger sum = 0;\n"
        "        for (int i = 0; i < 100; i++) {\n"
        "            sum += i;\n"
        "        }\n"
        "        dispatch_async(dispatch_get_main_queue(), ^{\n"
        "            NSLog(@\"%ld\", (long)sum);\n"
        "        });\n"
        "    });",
        
        "    NSDate *date = [NSDate date];\n"
        "    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];\n"
        "    [formatter setDateFormat:@\"yyyy-MM-dd HH:mm:ss\"];\n"
        "    NSString *dateString = [formatter stringFromDate:date];\n"
        "    NSLog(@\"%@\", dateString);"
    };
    
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> dist(0, bodies.size() - 1);
    
    return bodies[dist(rng)];
}

QString TrashCodeGenerator::generateRandomParameters()
{
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> paramCount(0, 2);
    
    int count = paramCount(rng);
    if (count == 0) {
        return "";
    }
    
    RandomGenerator gen;
    QStringList params;
    QStringList types = {"NSString *", "NSInteger", "BOOL", "id", "NSArray *"};
    
    for (int i = 0; i < count; i++) {
        std::uniform_int_distribution<int> typeIdx(0, types.size() - 1);
        QString paramName = gen.generateIdentifier(6);
        QString paramType = types[typeIdx(rng)];
        
        if (i == 0) {
            params << QString(":(%1)%2").arg(paramType).arg(paramName);
        } else {
            QString label = gen.generateIdentifier(4);
            params << QString(" %1:(%2)%3").arg(label).arg(paramType).arg(paramName);
        }
    }
    
    return params.join("");
}

QString TrashCodeGenerator::generateSwiftTrashMethod()
{
    RandomGenerator gen;
    QString methodName = gen.generateIdentifier(10);
    
    return QString("    private func %1() {\n"
                  "        let value = Int.random(in: 0..<100)\n"
                  "        print(\"Generated: \\(value)\")\n"
                  "    }\n").arg(methodName);
}

QString TrashCodeGenerator::generateJavaTrashMethod()
{
    RandomGenerator gen;
    QString methodName = gen.generateIdentifier(10);
    
    return QString("    private void %1() {\n"
                  "        Random random = new Random();\n"
                  "        int value = random.nextInt(100);\n"
                  "        System.out.println(\"Generated: \" + value);\n"
                  "    }\n").arg(methodName);
}